/*
 *  WsvJdbc - a JDBC driver for WSV (values separated by whatever) data files
 *  Copyright (C) 2004  Daniele Pes
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
  
package axs.jdbc.utils;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.DriverManager;


public class UrlUtils {
	public static final String WIN_FILE_PROT_BACK_FORMAT = "file:\\\\\\";
	public static final String STD_WIN_FILE_PROT_BACK_FORMAT = "file:\\\\";
	public static final String STANDARD_FILE_PROT_FORMAT = "file://";
	public static final String WIN_FILE_PROT_FORW_FORMAT = "file:///";
	
	public static final String FILE_PROTOCOL = "file";
	
	public static URL verifyAndSetUrl(String path) 
	throws MalformedURLException {
		URL    result   = new URL(path);
		String protocol = result.getProtocol(); 						
		if(protocol.equals(FILE_PROTOCOL)) {
			// note: a remote path must be absolute -> if filePath is not absolute, then it's assumed to be a local path			
			// if protocol == file then parameter path is assumed to be well formed (this must be verified in the calling scope) 
			File f = new File(result.getFile());										
			if(!f.exists())
				throw new MalformedURLException("invalid (local path) URL (path: " + result.getPath() + ")");				
		}
		
		return result;
	}

	
	private static String getAbsolutePath(String filePath) 
	throws MalformedURLException{
		String path = filePath;
		File f = new File(filePath);
		if(!f.isAbsolute()){ // note: a remote path must be absolute -> if filePath is not absolute, then it's assumed to be relative
			f = new File(".");			
			String absolutePath = f.getAbsolutePath(); 
			path = absolutePath.substring(0, absolutePath.length()-1) + filePath;
		}
		return path;	
	}

	
	/**
	 * @param filePath
	 * @return
	 */
	public static String getNormalizedPath(String filePath) {
		String r = null;
		URL tmpUrl;
		try {
			tmpUrl 				  = new URL(filePath);			
			String normProtocol = tmpUrl.getProtocol();
			String auth         = tmpUrl.getAuthority();
			
			String normPath;
			if(normProtocol.equals(UrlUtils.FILE_PROTOCOL)) {
				// for robustness
				if (SysUtils.isWindowsLike() && !auth.equals("")){					
					normProtocol = UrlUtils.WIN_FILE_PROT_FORW_FORMAT;
					if (filePath.indexOf(UrlUtils.WIN_FILE_PROT_FORW_FORMAT)==-1) { // it's a win URL having no 'file:///' format
						filePath = UrlUtils.normalizeWinProtocol(filePath);
						tmpUrl = new URL(filePath);
						auth = tmpUrl.getAuthority();
					}				
				}
				else{
					if(!SysUtils.isWindowsLike())
						normProtocol = UrlUtils.STANDARD_FILE_PROT_FORMAT;
					else
						normProtocol = UrlUtils.WIN_FILE_PROT_FORW_FORMAT;
				}				
				String file = SysUtils.isWindowsLike() && (tmpUrl.getFile().startsWith("/") || tmpUrl.getFile().startsWith("\\")) ? tmpUrl.getFile().substring(1): tmpUrl.getFile();
				normPath 	  = getAbsolutePath(auth + file);										
			}
			else{
				normProtocol += "://" + auth;
				normPath 	  = tmpUrl.getFile();
			}				
						
			String port = tmpUrl.getPort()==-1? "": ":" + String.valueOf(tmpUrl.getPort());			 
			r 			   = normProtocol + port + SysUtils.getPath(normPath);
		}
		catch (MalformedURLException e) {
			DriverManager.println("Unable to get a valid path pointing to data file (" + e.getMessage() + ")\ntrace is:\n" + e.getStackTrace());
		}		
		return r;
	}
	
	private static String normalizeWinProtocol(String filePath) {
		filePath = filePath.replaceAll(UrlUtils.STANDARD_FILE_PROT_FORMAT, UrlUtils.WIN_FILE_PROT_FORW_FORMAT);
		if(filePath.indexOf(UrlUtils.WIN_FILE_PROT_BACK_FORMAT)==-1) // it's a win URL having no 'file:\\\' format
			filePath = filePath.replaceAll(UrlUtils.STD_WIN_FILE_PROT_BACK_FORMAT, UrlUtils.WIN_FILE_PROT_FORW_FORMAT);
		else
			filePath = filePath.replaceAll(UrlUtils.WIN_FILE_PROT_BACK_FORMAT, UrlUtils.WIN_FILE_PROT_FORW_FORMAT);
		return filePath;
	}
	
}
